package com.boot.security.filter;

import com.boot.security.config.WhiteConfig;
import com.boot.security.exception.AuthExeHandler;
import com.boot.security.service.AuthTokenService;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;

/**
 * @author 公众号:知了一笑
 * @since 2023-07-23 12:42
 */
@Component
public class AuthTokenFilter extends OncePerRequestFilter {

    @Resource
    private AuthTokenService authTokenService ;

    @Resource
    private AuthExeHandler authExeHandler ;

    @Override
    protected void doFilterInternal(@Nonnull HttpServletRequest request,
                                    @Nonnull HttpServletResponse response,
                                    @Nonnull FilterChain filterChain) throws ServletException, IOException {
        String uri = request.getRequestURI();
        if (Arrays.asList(WhiteConfig.whiteList()).contains(uri)){
            // 如果是白名单直接放行
            filterChain.doFilter(request,response);
        } else {
            String token = request.getHeader("Auth-Token");
            if (Objects.isNull(token) || token.isEmpty()){
                // Token不存在，拦截返回
                authExeHandler.commence(request,response,null);
            } else {
                Object object = authTokenService.getToken(token);
                if (!Objects.isNull(object) && object instanceof User user){
                    UsernamePasswordAuthenticationToken authentication =
                            new UsernamePasswordAuthenticationToken(user, null,user.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    filterChain.doFilter(request,response);
                } else {
                    // Token验证失败，拦截返回
                    authExeHandler.commence(request,response,null);
                }
            }
        }
    }
}
